/*---------------------------------------------------------------------------
    $Workfile		: Connect.cpp $

    Author			: Joseph Chacko, Ajith Joseph
    Last $Modtime	: 1/12/2011 
    Last $Revision	: 1 $
	Remark			: None
    $History		: Connect.cpp $
 ---------------------------------------------------------------------------*/


// This is the main DLL file.

#include "stdafx.h"
#include "Connect.h"
#include "AndroidDotNetSettingsForm.h"
#include "NewAndroidProject.h"

using namespace System::Windows::Forms;


void AndroidDotNET::Connect::OnAddInsUpdate(System::Array ^%custom)
{
}

void AndroidDotNET::Connect::OnBeginShutdown(System::Array ^%custom)
{
}

void AndroidDotNET::Connect::OnConnection(System::Object ^Application, ext_ConnectMode ConnectMode, System::Object ^AddInInst, System::Array ^%custom)
{
	_applicationObject = dynamic_cast<DTE2^>(Application);
	
    _addInInstance = dynamic_cast<AddIn^>(AddInInst);
	
	m_ADNManager= gcnew CAndroidDotNetManager(_applicationObject);

	m_ADNManager->LoadAndroidSDKSettings();
	

    if((ConnectMode == ext_ConnectMode::ext_cm_UISetup)||(ConnectMode ==ext_ConnectMode::ext_cm_Startup))
	{
		Command ^NewCommand=nullptr;
		Command ^OpenCommand=nullptr;
		Command ^AboutCommand=nullptr;
	
		Command ^CompileCommand=nullptr;
		Command ^RunCommand=nullptr;
		Command ^DebugCommand=nullptr;
		Command ^SettingsCommand=nullptr;
		Command ^EmulatorCommand=nullptr;
		Command ^NewEmulatorCommand=nullptr;
		CommandBarPopup^ AndroidCommandBar=nullptr;

        array< Object^ >^ contextGUIDs = gcnew array< Object^ >(0);
        Commands2 ^commands = dynamic_cast<Commands2^>(_applicationObject->Commands);
        String ^toolsMenuName;

        try
        {
            //If you would like to move the command to a different menu, change the word "Tools" to the 
            //  English version of the menu. This code will take the culture, append on the name of the menu
            //  then add the command to that menu. You can find a list of all the top-level menus in the file
            //  CommandBar.resx.
            ResourceManager ^resourceManager = gcnew ResourceManager("AndroidDotNET.CommandBar", Assembly::GetExecutingAssembly());
            CultureInfo ^cultureInfo = gcnew System::Globalization::CultureInfo(_applicationObject->LocaleID);
			if(cultureInfo->TwoLetterISOLanguageName == "zh")
			{
				CultureInfo ^parentCultureInfo = cultureInfo->Parent;
				toolsMenuName = resourceManager->GetString(String::Concat(parentCultureInfo->Name,"File"));
			}
			else
			{
				toolsMenuName = resourceManager->GetString(String::Concat(cultureInfo->TwoLetterISOLanguageName,"File"));
				
			}
        }
        catch(...)
        {
            //We tried to find a localized version of the word Tools, but one was not found.
            //  Default to the en-US word, which may work for the current culture.
           toolsMenuName ="File" ;
        }

        //Place the command on the tools menu.
        //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
        _CommandBars ^commandBars = dynamic_cast<CommandBars^>(_applicationObject->CommandBars);
        CommandBar ^menuBarCommandBar = dynamic_cast<CommandBar^>(commandBars["MenuBar"]);

        //Find the Tools command bar on the MenuBar command bar:
        CommandBarControl ^toolsControl = menuBarCommandBar->Controls[toolsMenuName];
		 CommandBarPopup ^toolsPopup = dynamic_cast<CommandBarPopup^>(toolsControl);
		
		CommandBarPopup ^NewCommandBar = dynamic_cast<CommandBarPopup^>(toolsPopup->Controls["New"]);

		CommandBarPopup ^OpenCommandBar = dynamic_cast<CommandBarPopup^>(toolsPopup->Controls["Open"]);


		System::String^ strAndroidMainMenu="AndroidStudio";
		
		try
		{
			CommandBarPopup^ AndroidBar=dynamic_cast<CommandBarPopup^>(menuBarCommandBar->Controls[strAndroidMainMenu]);
			if(AndroidBar)
			{
				AndroidBar->Delete(true);
			}
		}
		catch(System::ArgumentException^ )
        {

		}

		AndroidCommandBar = dynamic_cast<CommandBarPopup^> (menuBarCommandBar->Controls->Add(MsoControlType::msoControlPopup, Type::Missing, Type::Missing, 4, true));
        AndroidCommandBar->Caption = strAndroidMainMenu;
		
		//This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in,
        //  just make sure you also update the QueryStatus/Exec method to include the new command names.
		
		
        try
        {	
			NewCommand=GetCommandObject("AndroidDotNET.Connect.NewAndroidProject");
			if(NewCommand)
			{
				NewCommand->Delete();
			}

            //Add a command to the Commands collection:
            NewCommand = commands->AddNamedCommand2(_addInInstance, "NewAndroidProject", "New Android Project", "New Android Project", true, 512, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);

			//Add a control for the command to the tools menu:
            if((NewCommand) && (NewCommandBar))
            {
                NewCommand->AddControl(NewCommandBar->CommandBar, 1);
				
            }
        }
		catch(...)//System::ArgumentException ^argumentException)
        {
			//If we are here, then the exception is probably because a command with that name
			//  already exists. If so there is no need to recreate the command and we can 
            //  safely ignore the exception.
        }
		
		
		try
		{
			OpenCommand=GetCommandObject("AndroidDotNET.Connect.OpenAndroidProject");
			
			if(OpenCommand)
			{
				OpenCommand->Delete();
			}

			OpenCommand = commands->AddNamedCommand2(_addInInstance, "OpenAndroidProject", "Open Android Project", "Open Android Project", true, 23, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);
			
			 if((OpenCommand) && (OpenCommandBar))
            {
                OpenCommand->AddControl(OpenCommandBar->CommandBar, 1);
            }
		}
		catch(...)//System::ArgumentException ^argumentException)
        {
			//If we are here, then the exception is probably because a command with that name
			//  already exists. If so there is no need to recreate the command and we can 
            //  safely ignore the exception.
        }
		try
		{
			OpenCommand=GetCommandObject("AndroidDotNET.Connect.OpenAndroidProjectFolder");
			
			if(OpenCommand)
			{
				OpenCommand->Delete();
			}

			OpenCommand = commands->AddNamedCommand2(_addInInstance, "OpenAndroidProjectFolder", "Open Android Project Folder", "Open Android ProjectFolder", true, 1791, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);
			
			 if((OpenCommand) && (OpenCommandBar))
            {
                OpenCommand->AddControl(OpenCommandBar->CommandBar, 2);
            }
		}
		catch(...)//System::ArgumentException ^argumentException)
        {
			//If we are here, then the exception is probably because a command with that name
			//  already exists. If so there is no need to recreate the command and we can 
            //  safely ignore the exception.
        }

		try
        {	
			//Add a command to the Commands collection:
			//System::Drawing::Image^ AddImage= System::Drawing::Image::FromFile("Icons\\application_add.jpg");
			CompileCommand=GetCommandObject("AndroidDotNET.Connect.CompileAndroidPrj");

			if(CompileCommand)
			{
				CompileCommand->Delete();
			}
			CompileCommand = commands->AddNamedCommand2(_addInInstance, "CompileAndroidPrj", "Compile the Project", "Compile the Android Project", true, 459, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);
			if(CompileCommand)
            {
			CompileCommand->AddControl(AndroidCommandBar->CommandBar,AndroidCommandBar->Controls->Count+1);
		    }
			else
			{

			}

			//Add a control for the command to the tools menu}
		}
		catch(System::ArgumentException ^argumentException)
        {
			//If we are here, then the exception is probably because a command with that name
			//  already exists. If so there is no need to recreate the command and we can 
            //  safely ignore the exception.
			System::Windows::Forms::MessageBox::Show(argumentException->Message);
        }
		try
        {	
            //Add a command to the Commands collection:
			//System::Drawing::Image^ AddImage= System::Drawing::Image::FromFile("Icons\\application_add.jpg");
			DebugCommand=GetCommandObject("AndroidDotNET.Connect.DebugAndroidPrj");
			if(DebugCommand)
			{
				DebugCommand->Delete();
			}
			DebugCommand = commands->AddNamedCommand2(_addInInstance, "DebugAndroidPrj", "Debug the Project", "Debug the Android Project", true, 1924, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);
			if(DebugCommand)
            {
				DebugCommand->AddControl(AndroidCommandBar->CommandBar,AndroidCommandBar->Controls->Count+1);
			}
			//Add a control for the command to the tools menu:
		}
		catch(System::ArgumentException ^argumentException)
        {
			//If we are here, then the exception is probably because a command with that name
			//  already exists. If so there is no need to recreate the command and we can 
            //  safely ignore the exception.
			System::Windows::Forms::MessageBox::Show(argumentException->Message);
        }
		try
        {	
            //Add a command to the Commands collection:
			//System::Drawing::Image^ AddImage= System::Drawing::Image::FromFile("Icons\\application_add.jpg");
			RunCommand=GetCommandObject("AndroidDotNET.Connect.RunAndroidPrj");

			if(RunCommand)
			{
				RunCommand->Delete();
			}
			RunCommand = commands->AddNamedCommand2(_addInInstance, "RunAndroidPrj", "Run the Project", "Run the Android Project", true, 186, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);

			if(RunCommand)
            {
				RunCommand->AddControl(AndroidCommandBar->CommandBar,AndroidCommandBar->Controls->Count+1);
			}

            //Add a control for the command to the tools menu:
            
        }
		catch(System::ArgumentException ^argumentException)
        {
			//If we are here, then the exception is probably because a command with that name
			//  already exists. If so there is no need to recreate the command and we can 
            //  safely ignore the exception.
			System::Windows::Forms::MessageBox::Show(argumentException->Message);
        }
		
		
		try
        {	
            //Add a command to the Commands collection:
			//System::Drawing::Image^ AddImage= System::Drawing::Image::FromFile("Icons\\application_add.jpg");
			EmulatorCommand=GetCommandObject("AndroidDotNET.Connect.EmulatorAndroidPrj");

			if(EmulatorCommand)
			{
				EmulatorCommand->Delete();
			}
			EmulatorCommand = commands->AddNamedCommand2(_addInInstance, "EmulatorAndroidPrj", "Invoke the Android Emulator", "Invoke the Android Emulator", true, 216, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);

			if(EmulatorCommand)
            {
				EmulatorCommand->AddControl(AndroidCommandBar->CommandBar,AndroidCommandBar->Controls->Count+1);
			}

            //Add a control for the command to the tools menu:
		}
		catch(System::ArgumentException ^argumentException)
        {
			//If we are here, then the exception is probably because a command with that name
			//  already exists. If so there is no need to recreate the command and we can 
            //  safely ignore the exception.
			System::Windows::Forms::MessageBox::Show(argumentException->Message);
        }
		try
        {	
            //Add a command to the Commands collection:
			//System::Drawing::Image^ AddImage= System::Drawing::Image::FromFile("Icons\\application_add.jpg");
			SettingsCommand=GetCommandObject("AndroidDotNET.Connect.SettingsAndroidPrj");

			if(SettingsCommand)
			{
				SettingsCommand->Delete();
			}
			SettingsCommand = commands->AddNamedCommand2(_addInInstance, "SettingsAndroidPrj", "AndroidStudio Settings ", "AndroidStudio Settings", true, 2144, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);

			if(SettingsCommand)
            {
				SettingsCommand->AddControl(AndroidCommandBar->CommandBar,AndroidCommandBar->Controls->Count+1);
			}

            //Add a control for the command to the tools menu:
		}
		catch(System::ArgumentException ^argumentException)
        {
			//If we are here, then the exception is probably because a command with that name
			//  already exists. If so there is no need to recreate the command and we can 
            //  safely ignore the exception.
		System::Windows::Forms::MessageBox::Show(argumentException->Message);
        }
		
		try
		{	
			NewEmulatorCommand=GetCommandObject("AndroidDotNET.Connect.NewEmulator");
			if(NewEmulatorCommand)
			{
				NewEmulatorCommand->Delete();
			}
			NewEmulatorCommand = commands->AddNamedCommand2(_addInInstance, "NewEmulator", "Create New Emulator ", "Create New Emulator For AndroidStudio", true, 513, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);
			if(NewEmulatorCommand)
			{
				NewEmulatorCommand->AddControl(AndroidCommandBar->CommandBar,AndroidCommandBar->Controls->Count+1);
			}
		}
		catch(System::ArgumentException ^argumentException)
		{
			System::Windows::Forms::MessageBox::Show(argumentException->Message);
		}

		try
		{
			AboutCommand=GetCommandObject("AndroidDotNET.Connect.AboutAndroidPrj");
			if(AboutCommand)
			{
				AboutCommand->Delete();
			}
			AboutCommand = commands->AddNamedCommand2(_addInInstance, "AboutAndroidPrj", "About AndroidStudio  ", "AndroidStudio Settings", true, 984, contextGUIDs, (int)vsCommandStatus::vsCommandStatusSupported+(int)vsCommandStatus::vsCommandStatusEnabled, (int)vsCommandStyle::vsCommandStylePictAndText, vsCommandControlType::vsCommandControlTypeButton);
			if(AboutCommand)
			{
				AboutCommand->AddControl(AndroidCommandBar->CommandBar,AndroidCommandBar->Controls->Count+1);
			}
		}
		catch(System::ArgumentException ^argumentException)
		{
			System::Windows::Forms::MessageBox::Show(argumentException->Message);
		}
  }
}

void AndroidDotNET::Connect::OnStartupComplete(System::Array ^%custom)
{
}

void AndroidDotNET::Connect::OnDisconnection(ext_DisconnectMode removeMode, System::Array ^%custom)
{
}


void AndroidDotNET::Connect::Exec(String ^CmdName, vsCommandExecOption ExecuteOption, Object ^%VariantIn, Object ^%VariantOut, bool %handled)
{
    handled = false;
    if(ExecuteOption == vsCommandExecOption::vsCommandExecOptionDoDefault)
    {
        if(!CmdName->CompareTo("AndroidDotNET.Connect.NewAndroidProject"))
        {
			m_ADNManager->InvokeNewAndroidProject();
			
            handled = true;
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.OpenAndroidProject"))
        {
			m_ADNManager->InvokeNewAndroidProjectOpenMenu();
			
            handled = true;
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.OpenAndroidProjectFolder"))
        {
			m_ADNManager->InvokeNewAndroidProjectOpenFolder();

			handled = true;
            return;
        }
		
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.CompileAndroidPrj"))
        {
			m_ADNManager->InvokeCompileCommand();
			handled = true;
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.RunAndroidPrj"))
		{
			m_ADNManager->InvokeRunCommand();
			handled = true;
            return;
		}
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.DebugAndroidPrj"))
		{
			m_ADNManager->InvokeDebugCommand();
		    handled = true;
            return;
		}
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.SettingsAndroidPrj"))
		{
			m_ADNManager->InvokeSettingsCommand();
			handled = true;
            return;
		}
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.EmulatorAndroidPrj"))
		{
			m_ADNManager->InvokeAndroidEmulatorCommand();
			 handled = true;
            return;
		}
		
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.NewEmulator"))
		{
			m_ADNManager->InvokeNewEmulatorCommand();
			 handled = true;
            return;
		}
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.AboutAndroidPrj"))
		{
			m_ADNManager->InvokeAboutAndroidCommand();
			 handled = true;
            return;
		}
	}
}

void AndroidDotNET::Connect::QueryStatus(String ^CmdName, vsCommandStatusTextWanted NeededText, vsCommandStatus %StatusOption, Object ^%CommandText)
{
    if(NeededText == vsCommandStatusTextWanted::vsCommandStatusTextWantedNone)
    {
        if(!CmdName->CompareTo("AndroidDotNET.Connect.NewAndroidProject"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.OpenAndroidProject"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.OpenAndroidProjectFolder"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.CompileAndroidPrj"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.RunAndroidPrj"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.DebugAndroidPrj"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.SettingsAndroidPrj"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.EmulatorAndroidPrj"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.NewEmulator"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
		else if(!CmdName->CompareTo("AndroidDotNET.Connect.AboutAndroidPrj"))
        {
            StatusOption = (vsCommandStatus)(vsCommandStatus::vsCommandStatusSupported+vsCommandStatus::vsCommandStatusEnabled);
            return;
        }
	}
}

Command ^ AndroidDotNET::Connect::GetCommandObject(System::String^ strCommand)
{
	Command ^ MyCertCommand;
	Commands2 ^commands = dynamic_cast<Commands2^>(_applicationObject->Commands);

	System::Collections::IEnumerator^ PEnumerator= commands->GetEnumerator();
	while(PEnumerator->MoveNext())
	{
		Command ^Cmd=(Command^)PEnumerator->Current;
		if(Cmd->default==strCommand)
		{
			MyCertCommand=Cmd;
		}
	}
	return MyCertCommand;
}
